//
//  _SW__Weighted_Grid_GeneratorPlugIn.m
//  [SW] Weighted Grid Generator
//
//  Created by David Langford on 13/09/09.
//  Copyright (c) 2009 Sentient Worlds. All rights reserved.
//

/* It's highly recommended to use CGL macros instead of changing the current context for plug-ins that perform OpenGL rendering */
#import <OpenGL/CGLMacro.h>

#import "_SW__Weighted_Grid_GeneratorPlugIn.h"
#import "SWGrid.h"
#import "SWCell.h"

#define	kQCPlugIn_Name				@"[SW] Weighted Grid Generator"
#define	kQCPlugIn_Description		@"Will generate a weighted grid. The weight (0.0 - 1.0) is the intesity level with the highest highest red pixel count.\n\n\nThe structure output is [Row[cell[x, y, width, height, weight]]]\n\n\nCreated by David Langford, feel free to email me at langford.d@gmail.com if you have any questions or if you want me to add functionality for you. You are also free to modify the source code."

@implementation _SW__Weighted_Grid_GeneratorPlugIn

/*
Here you need to declare the input / output properties as dynamic as Quartz Composer will handle their implementation
@dynamic inputFoo, outputBar;
*/
// The order here is the reverse order on the patch
@dynamic 
		outputArray
		, inputDestinationWidthInUnits
		, inputDestinationHeightInUnits
		, inputDestinationXOffsetInUnits
		, inputDestinationYOffsetInUnits
		, inputHeightInPercent
		, inputWidthInPercent
		, inputYOriginInPercent
		, inputXOriginInPercent
		, inputNumberOfColumns
		, inputNumberOfRows
		, inputImage;

+ (NSDictionary*) attributes
{
	/*
	Return a dictionary of attributes describing the plug-in (QCPlugInAttributeNameKey, QCPlugInAttributeDescriptionKey...).
	*/
	
	return [NSDictionary dictionaryWithObjectsAndKeys:kQCPlugIn_Name, QCPlugInAttributeNameKey, kQCPlugIn_Description, QCPlugInAttributeDescriptionKey, nil];
}

+ (NSDictionary*) attributesForPropertyPortWithKey:(NSString*)key
{
	/*
	Specify the optional attributes for property based ports (QCPortAttributeNameKey, QCPortAttributeDefaultValueKey...).
	*/
	
	if([key isEqualToString:@"inputImage"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Image to analyse", QCPortAttributeNameKey, nil];
	if([key isEqualToString:@"inputNumberOfColumns"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Number of columns", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:5], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputNumberOfRows"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Number of Rows", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:5], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"outputArray"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Weighted Grid", QCPortAttributeNameKey, nil];
	if([key isEqualToString:@"inputWidthInPercent"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Width of grid (%)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:100], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputHeightInPercent"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Height of gird (%)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:100], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputXOriginInPercent"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"X Origin (%)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:0], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputYOriginInPercent"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Y Origin (%)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:0], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputDestinationWidthInUnits"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Dest. Width (units)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:1], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputDestinationHeightInUnits"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Dest. Height (units)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:1], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputDestinationXOffsetInUnits"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Dest. X Offset (units)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:0], QCPortAttributeDefaultValueKey
				, nil];
	if([key isEqualToString:@"inputDestinationYOffsetInUnits"])
		return [NSDictionary dictionaryWithObjectsAndKeys:@"Dest. Y Offset (units)", QCPortAttributeNameKey
				, [NSNumber numberWithFloat:0], QCPortAttributeDefaultValueKey
				, nil];
		
	return nil;
}

+ (QCPlugInExecutionMode) executionMode
{
	/*
	Return the execution mode of the plug-in: kQCPlugInExecutionModeProvider, kQCPlugInExecutionModeProcessor, or kQCPlugInExecutionModeConsumer.
	*/
	
	return kQCPlugInExecutionModeProcessor;
}

+ (QCPlugInTimeMode) timeMode
{
	/*
	Return the time dependency mode of the plug-in: kQCPlugInTimeModeNone, kQCPlugInTimeModeIdle or kQCPlugInTimeModeTimeBase.
	*/
	
	return kQCPlugInTimeModeNone;
}

- (id) init
{
	if(self = [super init]) {
		/*
		Allocate any permanent resource required by the plug-in.
		*/
	}
	
	return self;
}

- (void) finalize
{
	/*
	Release any non garbage collected resources created in -init.
	*/
	
	[super finalize];
}

- (void) dealloc
{
	/*
	Release any resources created in -init.
	*/
	
	[super dealloc];
}

@end

@implementation _SW__Weighted_Grid_GeneratorPlugIn (Execution)

- (BOOL) startExecution:(id<QCPlugInContext>)context
{
	/*
	Called by Quartz Composer when rendering of the composition starts: perform any required setup for the plug-in.
	Return NO in case of fatal failure (this will prevent rendering of the composition to start).
	*/
	
	return YES;
}

- (void) enableExecution:(id<QCPlugInContext>)context
{
	/*
	Called by Quartz Composer when the plug-in instance starts being used by Quartz Composer.
	*/
}

- (BOOL) execute:(id<QCPlugInContext>)context atTime:(NSTimeInterval)time withArguments:(NSDictionary*)arguments
{
	
	if (self.inputImage)
	{
		// Create the grid
		SWGrid* grid = [[SWGrid alloc] initWithNumberOfColumns: self.inputNumberOfColumns
												  numberOfRows: self.inputNumberOfRows
													imageToUse: self.inputImage
												   withContext: context
												  widthPercent: self.inputWidthInPercent
												 heightPercent: self.inputHeightInPercent
												xOriginPercent: self.inputXOriginInPercent
												yOriginPercent: self.inputYOriginInPercent
									   destinationWidthInUnits: self.inputDestinationWidthInUnits
									  destinationHeightInUnits: self.inputDestinationHeightInUnits
												xOffsetInUnits: self.inputDestinationXOffsetInUnits
												yOffsetInUnits: self.inputDestinationYOffsetInUnits];
		
		// Output this grid
		self.outputArray = [grid asNSArray];
		
		// Don't need the grid anymore so release it
		[grid release];
		
	}

	return YES;
}

- (void) disableExecution:(id<QCPlugInContext>)context
{
	/*
	Called by Quartz Composer when the plug-in instance stops being used by Quartz Composer.
	*/
}

- (void) stopExecution:(id<QCPlugInContext>)context
{
	/*
	Called by Quartz Composer when rendering of the composition stops: perform any required cleanup for the plug-in.
	*/
}

@end
